Having covered modules for both the main and renderer processes, we can now take a look at the very
important IPSI messaging modules used to communicate between these processes.
IPC stands for Inter Process Communication.
And if you recall from the lesson on the remote module, this is what the remote module uses to communicate
with the main process from the renderer.
The reason I've separated this topic into its own section then is that ELECTRON provides us two modules
for IPSI messaging, IPC main for handling epoxy on the main process and epoxy renderer for use in the
renderer process.
These two modules relying on each other in order to implement IPSI.
I'll start in Mendes's where we'll be using epoxy Maine.
So require that module from electron epoxy main.
This now allowing us to send messages to a renderer process or browser window and listen for incoming
messages.
If we look at the documentation for this module, we see it's relatively simple.
This very much resembling a standard event šemeta module.
We can start by listening for a message from the main window renderer process in the global scope,
say IPSI Main on which can also be once.
Should you want to remove the listener after receiving the first message event.
I'll stick to on for now with the first parameter being the channel on which to listen channels being
unique, identifiers on which to send and listen for messages.
Naming this Channel one the actual name of the channel having absolutely no meaning.
But listening on Channel one like this means only messages sent to this channel from the renderer will
be received, basically providing a way to identify and organize ABC traffic.
This takes a callback to execute when receiving a message, first parameter being the event object and
secondly, the data received args which are logout for now.
I have my terminal window on my desktop this time around, so shift main window to the left of it,
sitting next to 100 pixels and why 140, which makes it vertically centered on my display.
OK, now, having this listener on the main process, the next obvious step is to send something to
this channel over to render the James.
This time requiring IPSI renderer.
Require electron, I'll execute the epoxy sent from a button click, so add a click listener will create
the button in a second document doget element by I.D. talk being the ID will assign to that button add
event listener click with a callback e being the callback event in which will send a message to the
main process.
First, create this talk button in index dot Demel a button with I.D. talk label.
This talk to mean process and a break to keep this on its own line there.
I'll save this and close it as we won't be doing anything else with this file and now having that button
hooked up, we can implement an epoxy send method to the main process, this time with the epoxy renderer
module Epoxy Renderer DOT send on the channel named Channel One, which is the channel we are listening
on in the main process, sending a simple string of hello from main window.
Save both files.
As mentioned, I have my terminal open so we can see as the message from the main window is received
on the main process.
Click that talk button and it works.
We get that locked in the terminal from the main process listener.
Now let's say we want to respond to this message from the main process where it was received.
To do this, we have to first understand the nature of IPC by default.
IPC on electron is asynchronous, meaning this sends the message to the main process and moves on immediately.
There's no waiting for a response, no return value, nothing.
And this is a good thing as it essentially never causes any blocking of JavaScript execution in the
renderer process.
So to respond to a renderer message from the main process, step one is going to be identifying the
renderer.
The message came from, remember, a renderer being a browser window instant's so we can have many.
How we find the sender then is on the listener's event.
Object e dot sender sender being the web content instance of the sending browser window calling send.
Same as we did in the renderer.
We need to again specify a channel to send this on.
It could be the same channel it was received on or a different one.
Makes no difference really.
I'll send this over a new channel called Channel One Response.
Message received on Channel One.
Thank you so responding with a confirmation of having received this, then being asynchronous messaging
will now have to implement a listener for this response in the sender main window.
Copy this channel name listening in Renderer dodges exactly the same as in Maine, dodges with epoxy
renderer on Channel one response.
That channel we're sending the response on pass a callback.
And logout ogg's, the data received.
Save both files again.
Click the talk button.
And immediately, as the main process receives our message on Channel One, it responds on Channel one
response, which we listen for and log out back in our main window.
So really basic sending and listening on both ends.
Now, you might have noticed that ABC mine doesn't actually have a send method.
So how would we send directly from the main process to a renderer then?
If you recall a minute ago I mentioned that the sender is the Web content instance of the sending render
a process, which is exactly what we can use to send directly to a specific renderer.
Then, for example, to send a message directly to the main window renderer.
We can do so on the web content of this browser window instance, but we do have to wait for the web
content to finish loading so and create window, wait for the did finish load event as we've done a
few times now.
Main window dot web content on did finish load passing a callback in which we can now send an EPOXI
message to this window with main window dot web content dot send.
So essentially accessing the send method from this renderers web content is exactly the same as we do
when sending to the main process from the renderer.
I'll name this mailbox sending you have mail.
Then, as before, we'll have to listen for this in the renderer.
Duplicate this listener listening on channel mailbox again, logging out args save.
And they're immediately after the Web content is ready, that message is sent from the main protest
directly to this renderer.
Also, take note that so far I've only been sending simple strings back and forth.
But ABC can send other JavaScript data types as well.
For example, change this message to an object with a few properties.
Email right at stake.
Academy Dot TV and an integer say priority one save.
And there we receive the object in the renderer exactly as it was sent from the main process, object
being a more likely data structure for communicating via IPSI.
OK, so that covers the default asynchronous messages.
And whilst this is probably the best implementation for 99 percent of situations, IPC can also send
synchronous messages.
These behave significantly different to the default asynchronous messaging.
So let's see an example.
I'll start by listening for that synchronous message on the main process, using the same listener as
with the asynchronous messages.
Duplicate this one.
This time listening on sinc message again, just to provide a logical name for what we expecting on
this channel, I log the message data out again.
And now the main difference here is that when sending a Synchronoss message from the renderer, that
message demands a response and will block the entire renderer process until it's received.
So we'll have to handle this a bit differently on the main process.
First of all, implement the send on the renderer again in this talk buttons, click handler, duplicate
the send method, commenting out the asynchronous Channel one send this time calling send sync on Sync
message.
With the message waiting for response, which will receive, as with any standard Synchronoss JavaScript
code, as a return value of this function, that return value being set by the receiver, the main process
back in that listener set on the event objects return value property, a sink response from the main
process.
Assigning the response to a variable in the renderer response.
Lock that out.
Save both files and keep in mind what's going to happen here now, when I click, this will send a synchronous
message to the main process, meaning this entire window will be hanging until we get a response back
from the main process that return value click.
And there.
This obviously happened really quickly, but we received this waiting for response message on the main
process, a sign, a return value to the message event, which allows the renderer to continue execution
and log that value out.
Keep in mind that the synchronous part of this only happens in the renderer.
The main process is simply responding and of course, being no cannot be blocked at any time to better
demonstrate the nature of this process blocking.
I'll add a delay to that response from the main process.
First, though, in the renderer, create a log interval to observe the blocking with set interval.
Logging out, I.
Said I to one and increment I after each log, which I'll make one second, this is trivial, but will
just allow us to see the process blocking then in mind, always using a timeout delay, setting this
response.
I'll also comment about the send to the renderer.
Set time out, pass a callback, setting that return value after, say, four seconds, save both files.
We see the log each second, but when I send the message, everything blocks until four seconds later
that response value is set and the renderer can continue executing code.
So, as you can see, probably something you should avoid using most of the time.
But there will be situations where synchronous messaging will be required.
Just use it wisely.
That's basically it for the IPSI modules.
We do have a few basic helper functions also, but these are pretty self-explanatory.
The ability to unregister channel listen as being the major ones.
You'll find ABC messaging in almost every electron app, so make sure you have a good grasp on this
topic.
In the next lesson, we'll take a look at some slightly more advanced uses of IPSI.